package ee.project.linkedlist;

public class LinkedList {

	public LinkedList() {
		header = new ListNode(null);
	}

	public boolean isEmpty() {
		return header.next == null;
	}

	public void makeEmpty() {
		header.next = null;
	}

	public LinkedListItr zeroth() {
		return new LinkedListItr(header);
	}

	public LinkedListItr first() {
		return new LinkedListItr(header.next);
	}

	public void insert(Object x, LinkedListItr p) {
		if (p != null && p.current != null)
			p.current.next = new ListNode(x, p.current.next);
	}

	public LinkedListItr find(Object x) {
		/* 1 */ListNode itr = header.next;

		/* 2 */while (itr != null && !itr.element.equals(x))
			/* 3 */itr = itr.next;

		/* 4 */return new LinkedListItr(itr);
	}

	public LinkedListItr findPrevious(Object x) {
		ListNode itr = header;
		while (itr.next != null && !itr.next.element.equals(x))
			itr = itr.next;
		return new LinkedListItr(itr);
	}

	public void remove(Object x) {
		LinkedListItr p = findPrevious(x);

		if (p.current.next != null)
			p.current.next = p.current.next.next; // Bypass deleted node
	}

	public static void printList(LinkedList theList) {
		if (theList.isEmpty())
			System.out.print("Empty list");
		else {
			LinkedListItr itr = theList.first();
			for (; !itr.isPastEnd(); itr.advance())
				System.out.print(itr.retrieve() + " ");
		}

		System.out.println();
	}

	private ListNode header;

	public static void main(String[] args) {
		LinkedList theList = new LinkedList();
		LinkedListItr theItr;
		int i;

		theItr = theList.zeroth();
		printList(theList);

		for (i = 0; i < 10; i++) {
			theList.insert(new Integer(i), theItr);
			printList(theList);
			theItr.advance();
		}

		for (i = 0; i < 10; i += 2)
			theList.remove(new Integer(i));

		for (i = 0; i < 10; i++)
			if ((i % 2 == 0) != (theList.find(new Integer(i)).isPastEnd()))
				System.out.println("Find fails!");

		System.out.println("Finished deletions");
		printList(theList);
	}

}
